package cc.cc4414.cc03.core.handler;

import javax.validation.ConstraintViolationException;

import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import cc.cc4414.cc03.core.result.ResultEnum;
import cc.cc4414.cc03.core.result.ResultException;
import cc.cc4414.cc03.core.result.ResultVO;
import lombok.extern.slf4j.Slf4j;

/**
 * 异常统一处理，返回ResultVO
 * 
 * @author cc 2018年4月30日
 */
@RestControllerAdvice
@Slf4j
public class ControllerExceptionHandler {

	/**
	 * 未预期的异常
	 * 
	 * @param e Exception
	 * @return data为e.getMessage()
	 */
	@ExceptionHandler(value = Exception.class)
	public ResultVO<String> handlerException(Exception e) {
		log.error(e.getMessage(), e);
		ResultVO<String> resultVO = new ResultVO<>(ResultEnum.UNKNOWN_ERROR);
		resultVO.setData(e.getMessage());
		return resultVO;
	}

	/**
	 * 业务异常
	 * 
	 * @param e ResultException
	 * @return data为null
	 */
	@ExceptionHandler(value = ResultException.class)
	public ResultVO<Object> handlerResultException(ResultException e) {
		return new ResultVO<>(e);
	}

	/**
	 * 参数异常
	 * 
	 * @param e ConstraintViolationException
	 * @return data为e.getMessage()
	 */
	@ExceptionHandler(value = ConstraintViolationException.class)
	public ResultVO<String> handlerResultException(ConstraintViolationException e) {
		ResultVO<String> resultVO = new ResultVO<>(ResultEnum.PARAM_ERROR);
		resultVO.setData(e.getMessage());
		return resultVO;
	}

	/**
	 * 参数异常
	 * 
	 * @param e MethodArgumentNotValidException
	 * @return data为 参数: 错误信息
	 */
	@ExceptionHandler(value = MethodArgumentNotValidException.class)
	public ResultVO<String> handlerResultException(MethodArgumentNotValidException e) {
		ResultVO<String> resultVO = new ResultVO<>(ResultEnum.PARAM_ERROR);
		FieldError fieldError = e.getBindingResult().getFieldError();
		resultVO.setData(fieldError.getField() + ": " + fieldError.getDefaultMessage());
		return resultVO;
	}

	/**
	 * 参数异常
	 * 
	 * @param e MissingServletRequestParameterException
	 * @return data为e.getMessage()
	 */
	@ExceptionHandler(value = MissingServletRequestParameterException.class)
	public ResultVO<String> handlerResultException(MissingServletRequestParameterException e) {
		ResultVO<String> resultVO = new ResultVO<>(ResultEnum.PARAM_ERROR);
		resultVO.setData(e.getMessage());
		return resultVO;
	}
}
